package com.alipay.sporadic.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.alipay.api.response.AlipayTradePayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.sporadic.configuration.AliPayProperties;
import com.alipay.sporadic.service.OrderService;
import com.alipay.sporadic.service.SporadicPayService;
import com.google.zxing.WriterException;
import dto.OrderDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;
import utils.Payutil;
import vo.ResponseData;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.UUID;

/**
 * @program: sporadic
 * @description:
 * @author: LHD   QQ:1727865856
 * @create: 2019-11-01 08:54
 **/
@Service
@Slf4j
public class SporadicPayServiceImpl implements SporadicPayService {

    @Autowired
    private OrderService orderService;
    @Autowired
    private AliPayProperties aliPayProperties;

    @Override
    public String test() {
        return "hello world";
    }

    /**
     * 当面付-条码付
     * <p>
     * 商家使用扫码工具(扫码枪等)扫描用户支付宝的付款码
     *
     * @param paymentCode 付款码的号码
     *                    orderid 订单号
     */
    @Override
    public ResponseData<String> alipay(String paymentCode, String orderNo) {
        ResponseData<OrderDTO> orderDTOResponseData = orderService.queryByid(orderNo);
        if (orderDTOResponseData.getBody() == null) {
            throw new RuntimeException("订单不存在");
        }
        //总金额
        String totalAmount = orderDTOResponseData.getBody().getOrderActualAmount().toString();
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayProperties.getGatewayUrl(), aliPayProperties.getAppid(), aliPayProperties.getAppPrivateKey(), aliPayProperties.getFormate(), aliPayProperties.getCharset(), aliPayProperties.getAlipayPublicKey(), aliPayProperties.getSignType());
        AlipayTradePayRequest request = new AlipayTradePayRequest();
        request.setBizContent("{" +
                "    \"out_trade_no\":\"" + UUID.randomUUID().toString() + "\"," +
                "    \"scene\":\"bar_code\"," +
                "    \"auth_code\":\"" + paymentCode + "\"," +//即用户在支付宝客户端内出示的付款码，使用一次即失效，需要刷新后再去付款
                "    \"subject\":\"商品\"," +
                "    \"store_id\":\"NJ_001\"," +
                "    \"timeout_express\":\"2m\"," +
                "    \"total_amount\":\"" + totalAmount + "\"" +
                "  }");
        AlipayTradePayResponse execute = null;
        try {
            execute = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return new ResponseData<>(null, "支付异常");
        }
        System.out.println("支付:"+execute.getBody());
        String alipay_trade_pay_response = JSON.parseObject(execute.getBody()).getString("alipay_trade_pay_response");
        JSONObject jsonObject = JSON.parseObject(alipay_trade_pay_response);
        String code = jsonObject.getString("code");
        if (!code.equals("10000")) {
//            if (jsonObject.getString("sub_code").equals("ACQ.PAYMENT_AUTH_CODE_INVALID")) {
//                return new ResponseData<>(null, "请刷新付款码！当前付款无效!");
//            }
            //定义count轮寻超过30次取消订单
            int count = 0;
            String out_trade_no = jsonObject.getString("out_trade_no");
            String trade_no = jsonObject.getString("trade_no");
            while (true) {
                //判断用户支付订单超过30*5=150秒后取消交易 重新付款
                if (count == 10) {
                    //取消订单
                    AlipayTradeCancelRequest cancelRequest = new AlipayTradeCancelRequest();
                    cancelRequest.setBizContent("{" +
                            "    \"out_trade_no\":\"" + out_trade_no + "\"," +
                            "    \"trade_no\":\"" + trade_no + "\"}");
                    AlipayTradeCancelResponse cancelResponse = null;
                    try {
                        cancelResponse = alipayClient.execute(cancelRequest);
                        System.out.println("取消订单:"+cancelResponse.getBody());
                    } catch (AlipayApiException e) {
                        e.printStackTrace();
                    }
                    if (cancelResponse.isSuccess()) {
                        //如果订单取消成功返回订单支付超时！重新支付
                        return new ResponseData<>(null, "支付超时!请重新支付");
                    }
                }
                //支付状态为正在支付，则轮寻查询是否支付成功；如果成功则返回成功，如果失败则取消订单以防客户继续支付
                AlipayTradeQueryRequest queryRequest = new AlipayTradeQueryRequest();
                queryRequest.setBizContent("{" +
                        "    \"out_trade_no\":\"" + out_trade_no + "\"," +
                        "    \"trade_no\":\"" + trade_no + "\"}");
                AlipayTradeQueryResponse execute1 = null;
                try {
                    execute1 = alipayClient.execute(queryRequest);
                } catch (AlipayApiException e) {
                    throw new RuntimeException("订单支付异常！");
                }
                String queryresponse = JSON.parseObject(execute1.getBody()).getString("alipay_trade_query_response");
                JSONObject query = JSON.parseObject(queryresponse);
                System.out.println("查询:"+execute1.getBody());
                //trade_status:WAIT_BUYER_PAY说明是等待用户付款
                if (!query.getString("trade_status").equals("WAIT_BUYER_PAY")) {
                    System.out.println("成功！");
                    return new ResponseData<>(null);
                } else {
                    //如果没有支付成功我们考虑是不是条形码已过期

                    count++;
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    continue;
                }
            }
        }
        System.out.println(execute.getBody());
        if (execute.isSuccess()) {
            System.out.println("成功！");
            return new ResponseData<>(null);
        } else {
            System.out.println("失败");
            return new ResponseData<>(null, "订单支付失败");
        }

    }

    /**
     * 查询订单
     *
     * @param orderNo 交易订单号
     * @return 查询结果
     */
    @Override
    public String payquery(String orderNo) {
        return "";
    }

    /**
     * 退货
     *
     * @param orderNo 支付单号
     * @return 退货结果结果
     */
    @Override
    public String refund(String orderNo) {
        return "";
    }

    @Override
    public ResponseData<String> qrpay(String orderno) {
        ResponseData<OrderDTO> orderDTOResponseData = orderService.queryByid(orderno);
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayProperties.getGatewayUrl(), aliPayProperties.getAppid(), aliPayProperties.getAppPrivateKey(), aliPayProperties.getFormate(), aliPayProperties.getCharset(), aliPayProperties.getAlipayPublicKey(), aliPayProperties.getSignType());
        AlipayTradePrecreateRequest alipayTradePrecreateRequest=new AlipayTradePrecreateRequest();
        String money = orderDTOResponseData.getBody().getOrderActualAmount().toString();
        log.info("付款金额:"+money);
        alipayTradePrecreateRequest.setBizContent("{" +
                "    \"out_trade_no\":\""+orderDTOResponseData.getBody().getOrderId()+"\"," +//商户订单号
                "    \"total_amount\":\""+money+"\"," +
                "    \"subject\":\"商品\"," +
                "    \"store_id\":\"Lx"+orderDTOResponseData.getBody().getOrderMerchantId()+"\"," +
                "    \"timeout_express\":\"30m\"}");
        AlipayTradePrecreateResponse execute=null;
        try {
            execute = alipayClient.execute(alipayTradePrecreateRequest);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        String body = execute.getBody();
        System.out.println(body);
        JSONObject jsonObject = JSON.parseObject(body);
        JSONObject alipay_trade_precreate_response = JSON.parseObject(jsonObject.getString("alipay_trade_precreate_response"));
        String url = alipay_trade_precreate_response.getString("qr_code");
        String responesValue=null;
        try {
            BufferedImage qrCodeImge = Payutil.getQRCodeImge(url);
            ByteArrayOutputStream baso=new ByteArrayOutputStream(); //io输入流
            ImageIO.write(qrCodeImge,"png",baso);
            byte[] bytes=baso.toByteArray();
            BASE64Encoder encoder=new BASE64Encoder();
            String jpg_base64=encoder.encodeBuffer(bytes).trim();
            jpg_base64=jpg_base64.replaceAll("\n","").replaceAll("\r","");
            responesValue="data:image/png;base64,"+jpg_base64;
            return new ResponseData<>(responesValue);
        } catch (WriterException | IOException e) {
            e.printStackTrace();
            return new ResponseData<>(null,"付款码生成失败!");
        }

    }
    @Override
    public ResponseData<String> queryQrpay(String orderno) {
        AlipayClient alipayClient = new DefaultAlipayClient(aliPayProperties.getGatewayUrl(), aliPayProperties.getAppid(), aliPayProperties.getAppPrivateKey(), aliPayProperties.getFormate(), aliPayProperties.getCharset(), aliPayProperties.getAlipayPublicKey(), aliPayProperties.getSignType());
        AlipayTradeQueryRequest  queryRequest=new AlipayTradeQueryRequest();
        queryRequest.setBizContent("{" +
                "    \"out_trade_no\":\""+orderno+"\"}");
        AlipayTradeQueryResponse response=null;
        try {
            response=alipayClient.execute(queryRequest);
        } catch (AlipayApiException e) {
            e.printStackTrace();
            return new ResponseData<>(null,"失败！");
        }
        System.out.println(response.getBody());
        JSONObject alipay_trade_query_response = JSON.parseObject(JSON.parseObject(response.getBody()).getString("alipay_trade_query_response"));
        System.out.println(alipay_trade_query_response);
        if (alipay_trade_query_response.getString("trade_status").equals("TRADE_SUCCESS")||alipay_trade_query_response.getString("trade_status").equals("TRADE_FINISHED")){
            return new ResponseData<>(null);
        }else{
            return new ResponseData<>(null,"支付失败或取消！");
        }
    }

}
